/****************************************************************************
*
* Copyright (c) 2023  C*Core -   All Rights Reserved
*
* THIS SOFTWARE IS DISTRIBUTED "AS IS, " AND ALL WARRANTIES ARE DISCLAIMED,
* INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* PROJECT     : CCFC2011BC
* DESCRIPTION : I2C demo code
* HISTORY     : Initial version.
* @file     iic_demo.c
* @version  1.1
* @date     2023 - 02 - 20
* @brief    Initial version.
*
*****************************************************************************/

#include "iic_demo.h"
#include "iic_lld.h"
#include "console.h"
#include "demo.h"
#include "sys.h"
#include "intc_lld.h"

static i2c_master_state_t I2CMasterState_test;
static i2c_slave_state_t  I2CSlaveState_test;

/************************ Test buffer ************************/
static uint8_t const  TxBuff[20] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, \
                      0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA};

static uint8_t RxBuff[20];

static uint8_t const TxBuff_Response[20] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, \
                                   0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA};
/************************ Test buffer ************************/

/************************************************************************
 *    Functional declarations
 ************************************************************************/
static void IIC_Demo_Test_case1(void);
static void IIC_Demo_Test_case2(void);
static void IIC_Demo_Test_case3(void);
static void IIC_Demo_Test_case4(void);
static void IIC_Demo_Test_case5(void);
static void IIC_Demo_Test_case6(void);
static void IIC_Demo_Test_case7(void);
static void IIC_Demo_Test_case8(void);
static void IIC_Demo_Test_case9(void);
static void IIC_Demo_Test_case10(void);

static void IIC_Loop_Master_Test(void);
static void IIC_Loop_Slave_Test(void);
/************************************************************************
 *    Functional declarations
 ************************************************************************/

/*******************************************************************************
 * @brief      This case shall be test the master Transmit by interrupt.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case1(void)
{
    static uint8_t Dats_Length;

    uint8_t    i;
    Dats_Length = 10;

    I2CMasterState_test.slaveAddress = 0x31;

    I2C_LLD_Master_Init(I2C_0_index, &I2CMasterState_test);
    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    for (i = 0u; i < 200u; i++)
    {
        (void)I2C_LLD_Master_Transmit(I2C_0_index, TxBuff, Dats_Length, 1);
        (void)delayms(5);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the slave receive by interrupt.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case2(void)
{
    static uint8_t Dats_Length;

    uint8_t RxBuff_Temp[30];

    uint8_t    i;

    Dats_Length = 10;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2CSlaveState_test.slaveAddress = 0x31;

    I2C_LLD_Slave_Init(I2C_0_index, &I2CSlaveState_test);

    for (i = 0u; i < 200u; i++)
    {
        (void)I2C_LLD_Slave_Receive(I2C_0_index, RxBuff_Temp, Dats_Length);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the master receive by interrupt.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case3(void)
{
    uint8_t Dats_Length;
    uint8_t    i;
    Dats_Length = 10;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2CMasterState_test.slaveAddress = 0x30;

    I2C_LLD_Master_Init(I2C_0_index, &I2CMasterState_test);

     for (i = 0u; i < 200u ; i++)
    {
         (void)I2C_LLD_Master_Receive(I2C_0_index, RxBuff, Dats_Length, 1);
         (void)delayms(100);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the master receive by interrupt.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case4(void)
{
    uint8_t Dats_Length;
    uint8_t    i;
    Dats_Length = 10;

    I2CSlaveState_test.slaveAddress = 0x30;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Slave_Init(I2C_0_index, &I2CSlaveState_test);

    for (i = 0u; i < 200u ; i++)
    {
        (void)I2C_LLD_Slave_Transmit(I2C_0_index, TxBuff_Response, Dats_Length);
    }
}

/*******************************************************************************
 * @brief      This case shall be test the master receive by polling.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case5(void)
{
    uint8_t Dats_Length;

    uint8_t Slave_Address;

    uint8_t TR_Flag;    /** Transmit 0 Receive 1 **/
    uint8_t    i;
    Slave_Address = 0x30;
    TR_Flag = 0x01;
    Slave_Address = (Slave_Address << 1) + TR_Flag;

    Dats_Length = 10;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Polling_Master_Init(I2C_0_index);

    for (i = 0u; i < 1000u ; i++)
    {
        (void)I2C_LLD_Polling_Master_Receive((uint8_t)I2C_0_index, Dats_Length, RxBuff, Slave_Address);

    }
    I2C_LLD_Gpio_DeInit(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);
}

/*******************************************************************************
 * @brief      This case shall be test the slave transmit by polling.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case6(void)
{
    uint8_t Dats_Length;
    uint8_t Slave_Address;
    uint8_t    i;
    Dats_Length = 10;
    Slave_Address = 0x30;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Polling_Slave_Init(I2C_0_index, Slave_Address);

    for (i = 0u; i < 1000u ; i++)
    {
        (void)I2C_Lld_Polling_Slave_Transmit((uint8_t)I2C_0_index, TxBuff_Response, Dats_Length);
    }
    I2C_LLD_Gpio_DeInit(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);
}

/*******************************************************************************
 * @brief      This case shall be test the master transmit by polling.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case7(void)
{
    uint8_t Dats_Length;

    uint8_t TR_Flag;    /** Transmit 0 Receive 1 **/

    uint8_t Slave_Address;
    uint8_t i;

    Slave_Address = 0x30;
    TR_Flag = 0x0;
    Slave_Address = (Slave_Address << 1) + TR_Flag;

    Dats_Length = 20;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Polling_Master_Init(I2C_0_index);

    for (i = 0u; i < 1000u ; i++)
	{
    	(void)I2C_LLD_Pollling_Master_Transmit(I2C_0_index, Dats_Length, TxBuff, Slave_Address);
	}
    I2C_LLD_Gpio_DeInit(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);
}

/*******************************************************************************
 * @brief      This case shall be test the slave receive by polling.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case8(void)
{
    uint8_t Dats_Length;
    uint8_t Slave_Address;
    uint8_t    i;
    Slave_Address = 0x30;

    Dats_Length = 20;
    
    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Polling_Slave_Init(I2C_0_index, Slave_Address);
       	
	for (i = 0u; i < 1000u ; i++)
	{
		(void)I2C_LLD_Poliing_Slave_Receive(I2C_0_index, RxBuff, Dats_Length);
	}
	
	I2C_LLD_Gpio_DeInit(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);
}

/*******************************************************************************
 * @brief      This case shall be test the master transmit by DMA.
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case9(void)
{
    uint8_t Dats_Length;
    uint8_t    i;
    /** The first byte is the Slave address  **/
    uint8_t  const TxBuffdma[21] = {0x60, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, \
                              0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA};

    Dats_Length = 20;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Polling_Master_Init(I2C_0_index);

    for (i = 0u; i < 1000u ; i++)
    {
        I2C_LLD_Pollling_Master_Transmit_Dma(I2C_0_index, Dats_Length, TxBuffdma);
    }
    
    I2C_LLD_Gpio_DeInit(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);
}

/*******************************************************************************
 * @brief      This case shall be test the master receive by DMA.
 * @param[in]  uint8_t instance
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Demo_Test_case10(void)
{
    uint8_t Dats_Length;

	uint8_t Slave_Address;
	uint8_t    i;
	uint8_t TR_Flag;    /** Transmit 0 Receive 1 **/
	
	Slave_Address = 0x30;
	TR_Flag = 0x01;
	
	Slave_Address = (Slave_Address << 1) + TR_Flag;

    Dats_Length = 10;

    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Polling_Master_Init(I2C_0_index);

    for (i = 0u; i < 1000u ; i++)
    {
        I2c_LLD_Polling_Master_Receive_Dma((uint8_t)I2C_0_index, Dats_Length, RxBuff, Slave_Address);
    }
    
    I2C_LLD_Gpio_DeInit(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);
}



/*******************************************************************************
 * @brief      This case shall be used  test loop(Master device)
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Loop_Master_Test(void)
{
    uint8_t Dats_Length;

    Dats_Length = 15;

    I2CMasterState_test.slaveAddress = 0x30;

    (void)PSPRINTF("\n------------------------------------\n");
    (void)PSPRINTF("\n I2C Loop Test!\n");
    (void)PSPRINTF("\n Test Begin!\n");

    /** Master device send data buffer to slave device **/
    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2C_LLD_Master_Init(I2C_0_index, &I2CMasterState_test);

    (void)I2C_LLD_Master_Transmit(I2C_0_index, TxBuff, Dats_Length, 1);

    (void)delayms(10);

    /** Master device receive data buffer from slave device  **/
    I2C_LLD_Master_Init(I2C_0_index, &I2CMasterState_test);

    (void)I2C_LLD_Master_Receive(I2C_0_index, RxBuff, Dats_Length, 1);

    (void)delayms(10);

    if (memcmp(RxBuff, TxBuff, Dats_Length) == (int8_t)1)
    {
        (void)PSPRINTF("\n I2C Loop Test Fail \n");
    }
    else
    {
        (void)PSPRINTF("\n I2C Loop Test Pass \n");
    }
    (void)PSPRINTF("\n Test End!\n");
}

/*******************************************************************************
 * @brief      This case shall be the loop test(slave device).
 * @param[in]  None
 * @param[out] None
 * @retval
 * @notapi
*******************************************************************************/
static void IIC_Loop_Slave_Test(void)
{
    static uint8_t Dats_Length;

    Dats_Length = 15;

    /** Slave device receive data buffer from the master device **/
    I2C_LLD_Gpio_Init(I2C_0_index, (uint8_t)I2C_GPIO_DEFAULT);

    I2CSlaveState_test.slaveAddress = 0x30;

    I2C_LLD_Slave_Init(I2C_0_index, &I2CSlaveState_test);

    (void)I2C_LLD_Slave_Receive(I2C_0_index, RxBuff, Dats_Length);

    (void)delayms(100);

    /** Slave device send data buffer to the master device **/
    (void)I2C_LLD_Slave_Transmit(I2C_0_index, RxBuff, Dats_Length);
}

/******************************************************************************
   Function:        void IIC_Demo(void)
   Description:     IIC_Demo
   Parameters:      Input:    None
                    Output:   None
   Notes:            date 2022.06
 ******************************************************************************/
void IIC_Demo(void)
{
    INTC_IRQ_Enable();
    /* Function: Polling test(Master device) */
    #if I2C_MASTER_FLAG
    /** This case is used to test the loop test.
     *  step1: Master device transmit the buffer to the slave device.
     *  step2: Master device receive the buffer from the salve device
     *  step3: Master device compare the buffer and print the result **/
    IIC_Loop_Master_Test();
    #endif

    /* Function: Polling test(Slave device) */
    #if I2C_SLAVE_FLAG
    /** This case is used to test the loop test.
      * step1: Slave device receive the buffer from the Master device.
      * step2: Slave device transmit the buffer to the salve device  **/
    IIC_Loop_Slave_Test();
    #endif

    /* Function Master Transmit by Interrupt */
    #if I2C_CASE1  
    IIC_Demo_Test_case1(); 
    #endif

    /* Function Slave Receive by Interrupt */
    #if I2C_CASE2  
    IIC_Demo_Test_case2();   
    #endif

    /* Function Master Receive by Interrupt */
    #if I2C_CASE3  
    IIC_Demo_Test_case3();    
    #endif

    /* Function Slave Transmit by Interrupt */
    #if I2C_CASE4  
    IIC_Demo_Test_case4();     
    #endif

    /* Function Master Receive by Polling */
    #if I2C_CASE5  
    IIC_Demo_Test_case5();        
    #endif

    /* Function Slave Transmit by Polling */
    #if I2C_CASE6 
    IIC_Demo_Test_case6();         
    #endif

    /* Function Master Transmit by Polling */
    #if I2C_CASE7  
    IIC_Demo_Test_case7();      
    #endif

    /* Function Slave Receive by Polling */
    #if I2C_CASE8  
    IIC_Demo_Test_case8();          
    #endif

    /* Function Master Transmit by DMA */
    #if I2C_CASE9  
    IIC_Demo_Test_case9();    
    #endif
    
    /* Function Master Receive by DMA */
    #if I2C_CASE10  
    IIC_Demo_Test_case10();   
    #endif
}
